<template>
  <app-page :customNav="true" :login="false" :cusStyle="{ background: '#000000', minHeight: '100vh' }">
    <mxp-navbar
      title=""
      homePath="/pages/tab-bar/index1/index1"
      :borderColor="false"
      leftIconColor="#ffffff"
      titleWidth="0px"
      :placeholder="false"
      background="transparent"
    >
      <template #left>
        <text style="width: 480rpx; overflow: hidden; font-size: 15px; color: #ffffff; text-overflow: ellipsis; white-space: nowrap">
          {{ dramaTitle || '短剧' }}
        </text>
      </template>
    </mxp-navbar>
    <template v-if="pageLoadState">
      <swiper
        :circular="swiperCircular"
        :current="swiperIndex"
        :style="{ width: '100vw', background: '#000000', height: `${swiperHeight}px` }"
        :vertical="true"
        :indicatorDots="false"
        @change="myChange"
      >
        <template v-for="(item, _index) in swiperItemInfoList" :key="item?._id">
          <swiper-item class="swiper-item" :style="{ width: '100vw', height: `${swiperHeight}px` }">
            <template v-if="item">
              <mxp-app-video
                v-if="isMxpAppVideo"
                :id="item._id"
                :loop="false"
                :autoplay="false"
                :muted="muted"
                objectFit="cover"
                :src="item.episodeUrl || ''"
                :safeAreaInsetsBottom="safeAreaInsetsBottom"
                :cusStyle="{ width: '100vw', background: '#000000', height: `${swiperHeight}px` }"
                :poster="item.episodeCover || ''"
                @ended="ended"
                @loadedmetadata="() => swiperIndex === _index && videoSwiper?.onGetSource(item.episodeSeq!)"
              ></mxp-app-video>
              <video
                v-else
                :id="item._id"
                :loop="false"
                :muted="muted"
                :httpCache="true"
                :pageGesture="false"
                :autoplay="false"
                :showProgress="true"
                objectFit="cover"
                playBtnPosition="center"
                :showFullscreenBtn="false"
                :showLoading="false"
                :showCenterPlayBtn="false"
                :enableProgressGesture="true"
                :src="item.episodeUrl || ''"
                :style="{ width: '100vw', background: '#000000', height: `${swiperHeight}px` }"
                :poster="item.episodeCover || ''"
                @ended="ended"
                @loadedmetadata="() => swiperIndex === _index && videoSwiper?.onGetSource(item.episodeSeq!)"
                @controlstoggle="controlstoggle"
              ></video>
            </template>
            <template v-if="swiperIndex === _index && item.state === 'lock'">
              <!-- 解锁 -->
              <unlock-module
                :loading="data.unlockLoading"
                :currEpisodeIndex="currEpisodeIndex"
                :title="dramaTitle"
                @unlock="() => unlockDrama(currEpisodeIndex, true)"
              ></unlock-module>
            </template>
          </swiper-item>
        </template>
      </swiper>
      <!-- 运营 -->
      <album-operation
        :dramaCover="dramaCover"
        :isChasing="isChasing"
        :safeAreaInsetsBottom="`${safeAreaInsetsBottom + 36 + 100}px`"
        @chasingClick="changeChasingDrama()"
        @introClick="openIntroPopup"
      ></album-operation>
      <!-- 选集 -->
      <album-title-select
        :serialNo="currEpisodeIndex + 1"
        :totalSeqNum="seqNum"
        :bottom="titleBarBottom"
        :pointerEvents="true"
        :dramaTitle="dramaTitle"
        @openIntroClick="openIntroPopup"
      ></album-title-select>
    </template>
    <mxp-refresh-page v-else ref="mxpRefreshPageRef" :queryData="queryData"></mxp-refresh-page>
    <intro-popup ref="introPopupRef" :isThird="false" :dramaId="dramaId!" :currEpisodeIndex="currEpisodeIndex" :height="popupHeight"></intro-popup>
    <pay-popup ref="payPopupRef" :currEpisodeId="currEpisodeId" :currEpisodeIndex="currEpisodeIndex" :dramaId="dramaId"></pay-popup>
    <login-popup ref="loginPopupRef"></login-popup>
  </app-page>
</template>

<script setup lang="ts">
  import { onHide, onLoad, onShareAppMessage, onShow } from '@dcloudio/uni-app';
  import { computed, getCurrentInstance, nextTick, reactive, ref, watch } from 'vue';
  import AppPage from '@/components/app-page/app-page.vue';
  import PayPopup from './components/pay-popup.vue';
  import IntroPopup from '@/components/page/intro-popup/intro-popup.vue';
  import LoginPopup from './components/login-popup.vue';
  import MxpNavbar from '@/mxp-ui/mxp-navbar/mxp-navbar.vue';
  import MxpAppVideo from '@/mxp-ui/mxp-dom-video/mxp-dom-video.vue';
  import UnlockModule from '@/components/page/unlock-module/unlock-module.vue';
  import { type DramaEpisode, addChasingDramaAxios, addWatchDramaAxios, cancelChasingDramaAxios, getDramaInfoByIdAxios } from '@/api/drama';
  import type { SwiperOnChangeEvent, VideoPlayerOnControlstoggleEvent } from 'mxp-uni-types';
  import { type UnlockEpisodeUrlInfoMap, createDiamondUnlockOrderAxios } from '@/api/pay';
  import { autoLogin } from '@/utils/page/user';
  import { VideoSwiper } from './video-player';
  import { type PageParam, trimUnlockList, useBaseInfo } from './util';
  import AlbumTitleSelect from '@/components/page/album-title-select/album-title-select.vue';
  import AlbumOperation from '@/components/page/album-operation/album-operation.vue';
  import MxpRefreshPage, { type Ins } from '@/mxp-ui/mxp-refresh-page/mxp-refresh-page.vue';
  import { useRefresh } from '@/mxp-ui/mxp-tool/hooks/useHooksRefresh.ts';

  const { mxpRefreshPageRef } = useRefresh();
  const instance = getCurrentInstance();

  /** 页面加载状态 */
  const pageLoadState = ref(false);
  /** 剧目ID */
  const dramaId = ref(-1);
  /** 剧集ID */
  const currEpisodeId = ref(-1);
  /** 当前剧集的下标 */
  const currEpisodeIndex = ref(-1);
  /** 短剧封面图 */
  const dramaCover = ref('');
  /** 剧集列表 */
  const dramaEpisodeList = ref<DramaEpisode[]>([]);
  /** 短剧名称 */
  const dramaTitle = ref<string>('');
  /** 是否追剧：0-否；1-是 */
  const isChasing = ref<0 | 1>(0);
  /** 总集数 */
  const seqNum = ref<number>(0);

  const {
    sys,
    /** 自动解锁 */
    isAutoPay,
    /** 静音 */
    muted,
    /** 平台 */
    uniPlatform,
    /** 底部安全距离 */
    safeAreaInsetsBottom,
    /** appStore */
    appStore,
    /** 登录状态 */
    loginState,
    /** 底部标题栏的 Bottom 偏移 */
    popupHeight,
    /** 底部标题栏的 Bottom 偏移 */
    titleBarBottom,
    /** swiper高度 */
    swiperHeight,
  } = useBaseInfo();

  const data = reactive({
    /** 解锁状态 */
    unlockLoading: false,
    /** 追剧状态是否正在改变中 */
    chasingLoading: false,
    /** 底部标题栏的透明度 */
    titleBarOpacity: 1,
    /** 底部标题栏的PointerEvents */
    titleBarPointerEvents: 'auto' as 'auto' | 'none',
  });

  /** 是否使用<MxpAppVideo>组件 */
  const isMxpAppVideo = computed(() => uniPlatform.value === 'web' || uniPlatform.value === 'app');
  /** 是否采用衔接滑动，即播放到末尾后重新回到开头 */
  const swiperCircular = ref(true);
  /** 当前swiper的的下标 */
  const swiperIndex = ref(0);
  /** 当前播放列表，VideoSwiper 给到 */
  const swiperItemInfoList = ref<DramaEpisode[]>([]);
  /** VideoSwiper实例 */
  let videoSwiper: VideoSwiper | undefined = undefined;

  const payPopupRef = ref<InstanceType<typeof PayPopup> | null>(null);
  const introPopupRef = ref<InstanceType<typeof IntroPopup> | null>(null);
  const loginPopupRef = ref<InstanceType<typeof LoginPopup> | null>(null);

  const currEpisodeInfo = ref<DramaEpisode | undefined>(undefined);
  const init = ref(false);
  watch(
    () => currEpisodeIndex.value,
    (index) => {
      currEpisodeInfo.value = dramaEpisodeList.value[index]!;
      currEpisodeId.value = currEpisodeInfo.value.episodeId!;
      checkEpisodeInfo(index);
    }
  );

  watch(
    () => loginState.value,
    () => {
      if (loginState.value && init.value) {
        queryData()
          .then(() => {
            loginPopupRef.value?.hide();
            loginPopupRef.value?.hide();
            if (currEpisodeInfo.value?.state === 'lock') {
              unlockDrama(currEpisodeIndex.value, false);
            }
          })
          .catch((err) => {
            console.log('err====', err);
            uni.showToast({ title: '获取视频数据失败,BD0001', icon: 'none', position: 'bottom' });
          });
      }
    }
  );

  onShareAppMessage(() => {
    let url = `/pages/drama/playlet-public/playlet-public`;
    url += `?dramaId=${dramaId.value}&episodeId=${currEpisodeId.value}`;
    return {
      imageUrl: currEpisodeInfo.value!.episodeCover || '',
      title: `${dramaTitle.value || ''}(${currEpisodeInfo.value?.episodeTitle || `第${videoSwiper!.currentIndex + 1}集`})`,
      path: url,
    };
  });

  onLoad((param?: PageParam) => {
    currEpisodeId.value = param?.episodeId && !isNaN(Number(param?.episodeId)) ? Number(param?.episodeId) : -1;
    dramaId.value = param?.dramaId && !isNaN(Number(param?.dramaId)) ? Number(param?.dramaId) : -1;
  });

  onShow(() => {
    nextTick(() => {
      if (dramaEpisodeList.value[currEpisodeIndex.value]?.state !== 'lock') {
        videoSwiper?.play();
      }
    });
  });

  onHide(() => {
    videoSwiper?.pauseAll();
  });

  /**
   * 检查剧集信息，如要解锁则解锁
   */
  async function checkEpisodeInfo(newIndex: number) {
    const dramaEpisode = dramaEpisodeList.value[newIndex];
    if (dramaEpisode) {
      currEpisodeId.value = dramaEpisode.episodeId!;
      if (dramaEpisode?.state !== 'lock') {
        videoSwiper?.play();
        loginState.value && addWatchDramaAxios({ dramaId: dramaId.value, dramaEpisodeId: dramaEpisode!.episodeId! });
      } else {
        try {
          // 无权播放先解锁，后播放
          await unlockDrama(newIndex, false);
        } catch (error) {
          console.log('解锁出错1====', error);
        }
      }
    }
  }

  /**
   * 获取数据
   */
  async function queryData(ins?: Ins) {
    try {
      try {
        !appStore.loginState && (await autoLogin());
      } catch (error) {
        console.log('自动登录错误====', error);
      }
      const res = await getDramaInfoByIdAxios({ dramaId: dramaId.value!, referralLinkId: appStore.launchQuery?.referralLinkId });
      res.data.dramaEpisodeList = res.data.dramaEpisodeList || [];
      res.data.dramaEpisodeList.forEach((item) => {
        item._id = `id_${item.episodeId}`;
      });
      const _currEpisodeIndex = res.data.dramaEpisodeList.findIndex((item) => item.episodeId === currEpisodeId.value);
      if (_currEpisodeIndex < 0) {
        currEpisodeId.value = res.data.dramaEpisodeList[0]!.episodeId!;
        currEpisodeIndex.value = 0;
      } else {
        currEpisodeIndex.value = _currEpisodeIndex;
      }

      dramaEpisodeList.value = res.data.dramaEpisodeList || [];
      dramaCover.value = res.data.dramaCover;
      dramaTitle.value = res.data.dramaTitle || '';
      isChasing.value = res.data.isChasing || 0;
      seqNum.value = res.data.seqNum || 0;
      init.value = true;
      pageLoadState.value = true;

      videoSwiper = new VideoSwiper(dramaEpisodeList, {
        isMxpAppVideo: isMxpAppVideo.value,
        instance,
        start: currEpisodeIndex.value,
        total: dramaEpisodeList.value.length,
        /** swiperOptions 变化时触发，需要 更新 到页面中 */
        onSwiperOptionsChange(_swiperOptions) {
          swiperCircular.value = _swiperOptions.circular;
          swiperIndex.value = _swiperOptions.current;
        },
        /** 切换swiper-item时触发，返回 swiper-item的剧集信息列表，需要设置到页面渲染  */
        onSwiperItemInfoListChange(curQueue) {
          swiperItemInfoList.value = [...curQueue];
        },
      });
      ins?.setSuccess();
    } catch (error) {
      init.value = true;
      pageLoadState.value = false;
      ins?.setEmpty('fail_load', error.msg || '获取数据失败，BD001');
    }
  }

  /** Swiper 滑动事件 */
  function myChange(event: SwiperOnChangeEvent) {
    videoSwiper!.onchange(event);
    currEpisodeIndex.value = videoSwiper!.currentIndex;
  }

  /** 视频播放结束 */
  function ended() {
    videoSwiper!.onEnded();
  }

  /** 控件切换显示隐藏 */
  function controlstoggle(event: any) {
    const _event: VideoPlayerOnControlstoggleEvent = event?.detail?.type === 'controlstoggle' ? event.detail : event;
    maskChange(_event.detail.show);
  }

  /** 视频遮罩状态改变 */
  function maskChange(show: boolean) {
    if (sys.value.screenHeight - 40 >= 0) {
      data.titleBarOpacity = 1;
      data.titleBarPointerEvents = 'auto';
    } else {
      data.titleBarOpacity = show ? 0 : 1;
      data.titleBarPointerEvents = show ? 'none' : 'auto';
    }
  }

  /** 追剧 */
  async function changeChasingDrama() {
    if (!loginState.value) {
      loginPopupRef.value?.show();
    } else if (!data.chasingLoading) {
      try {
        data.chasingLoading = true;
        if (isChasing.value === 1) {
          await cancelChasingDramaAxios({ dramaId: dramaId.value! });
          isChasing.value = 0;
        } else {
          await addChasingDramaAxios({ dramaId: dramaId.value! });
          isChasing.value = 1;
        }
        data.chasingLoading = false;
      } catch (error) {
        data.chasingLoading = false;
        uni.showToast({ title: error.msg || '操作失败,BD001', icon: 'none', position: 'bottom' });
      }
    }
  }

  /** 显示简介弹出框 */
  async function openIntroPopup() {
    try {
      !appStore.loginState && (await autoLogin());
    } catch (error) {}
    nextTick(() => {
      if (!loginState.value) {
        loginPopupRef.value?.show();
      } else {
        introPopupRef.value?.show({
          /** 点击切换剧集的回调 */
          cutEpisode(index: number) {
            if (currEpisodeIndex.value !== index) {
              const dramaEpisode = dramaEpisodeList.value[index];
              if (dramaEpisode) {
                currEpisodeId.value = dramaEpisode.episodeId!;
                videoSwiper?.setStart(index);
                currEpisodeIndex.value = index;
              }
            }
          },
        });
      }
    });
  }

  /**
   * 解锁剧集
   * @param forceDiamondUnlock - 是否强制调用K币解锁（如直接点击解锁按钮，而不是滑动swiper，就需要强制调用）
   */
  async function unlockDrama(index: number, forceDiamondUnlock: boolean) {
    try {
      data.unlockLoading = true;
      !loginState.value && (await autoLogin());
    } catch (error) {
      data.unlockLoading = false;
      loginPopupRef.value?.show();
      return;
    }
    const dramaEpisode: DramaEpisode | undefined = dramaEpisodeList.value[index];
    if (dramaEpisode && dramaEpisode?.state === 'lock') {
      introPopupRef.value?.hide();
      if (isAutoPay.value || forceDiamondUnlock) {
        try {
          await setDiamondUnlock(dramaEpisode);
          nextTick(() => {
            videoSwiper?.updateCurrentVideo();
          });
        } catch (error) {
          openPayPopup(index);
        }
      } else {
        openPayPopup(index);
      }
      data.unlockLoading = false;
    } else if (dramaEpisode && dramaEpisode?.state !== 'lock') {
      data.unlockLoading = false;
      introPopupRef.value?.hide();
      nextTick(() => {
        currEpisodeIndex.value = index;
      });
    } else {
      data.unlockLoading = false;
      uni.showToast({ title: index >= dramaEpisodeList.value.length ? '本集前有未解锁的剧集暂无法观看' : '请从头开始解锁', icon: 'none', position: 'bottom' });
    }
  }

  /** K币解锁 (当前或下一集) */
  async function setDiamondUnlock(dramaEpisode: DramaEpisode) {
    try {
      data.unlockLoading = true;
      const res = await createDiamondUnlockOrderAxios({ episodeId: dramaEpisode.episodeId!, referralLinkId: appStore.launchQuery?.referralLinkId });
      if (res.data.unLockStatus === 1) {
        appStore.updateVirtualCoins(res.data.virtualCoins);
        dramaEpisodeList.value = trimUnlockList(dramaEpisodeList.value, res.data.episodeMap);
        currEpisodeInfo.value = dramaEpisodeList.value[currEpisodeIndex.value]!;
        currEpisodeId.value = currEpisodeInfo.value.episodeId!;
        data.unlockLoading = false;
        uni.showToast({ title: '解锁成功', icon: 'none', position: 'bottom' });
        return Promise.resolve(true);
      } else {
        data.unlockLoading = false;
        return Promise.reject({ code: -1001, msg: 'K币解锁失败,BDZS001' });
      }
    } catch (error) {
      data.unlockLoading = false;
      return Promise.reject(error || 'K币解锁失败');
    }
  }

  /** 打开支付弹出框 */
  function openPayPopup(index: number) {
    payPopupRef.value?.show({
      dramaTitle: dramaTitle.value!,
      /** 支付成功 */
      paySuccess(urlObj: UnlockEpisodeUrlInfoMap) {
        setUnlockDramaInfo(urlObj, index);
      },
    });
  }

  /**
   * 设置解锁信息
   */
  function setUnlockDramaInfo(urlObj: UnlockEpisodeUrlInfoMap, index: number) {
    dramaEpisodeList.value = trimUnlockList(dramaEpisodeList.value, urlObj);
    currEpisodeIndex.value = index;
    nextTick(() => {
      videoSwiper?.updateCurrentVideo();
      currEpisodeInfo.value = dramaEpisodeList.value[currEpisodeIndex.value]!;
      currEpisodeId.value = currEpisodeInfo.value.episodeId!;
      nextTick(() => {
        videoSwiper?.play();
      });
    });
  }
</script>

<style scoped lang="scss">
  .page-container {
    position: absolute;
    z-index: 0;
    display: flex;
    align-items: center;
    justify-content: center;
  }

  .swiper-item {
    position: relative;
    display: flex;
    flex-direction: column;
    align-items: center;
    justify-content: center;
  }

  .container {
    background-color: #000000;
  }

  .item {
    position: relative;
    background-color: #000000;
  }
</style>
